<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2018 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: 熊义 <34521664@qq.com> Date: 2025/4/33
// | 用于微信小程序的登录验证
// +----------------------------------------------------------------------
namespace plugins\xiongyi\controller;

use cmf\controller\PluginRestBaseController;
use think\Validate;
//use think\Db;
use think\facade\Db;

class WxappController extends PluginRestBaseController
{
    /**
     * 登录页
     * /plugin/xiongyi/Wxapp/onlogin
     */
    public function onlogin()
    {
        /** 微信小程序  */
        $appid = "wx85eb5c489516acbd";
        $appSecret = "48a453de8f1fb420a0520fbe983f8da7";
        $grant_type = "authorization_code";

        $validate = new Validate();
        $validate->rule([
            'code'           => 'require',
        ]);
        $validate->message([
            'code.require'           => '缺少参数code!',
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }

        $code          = $data['code'];

        $in_appid = $this->request->header('XX-Wxapp-AppId');
        //var_dump($appid);
        //var_dump($in_appid);
        if (strcmp($in_appid, $appid)) {
            $this->error('appid不一致！');            //与本程序使用appid不一致
        }

        //$deviceType = $this->request->header('XX-Device-Type');
        //if (empty($deviceType)) {
        //    $this->error('需要有header XX-Device-Type字段!');
        //}
        //if (!in_array($deviceType, $this->allowedDeviceTypes)) {
        //    $this->error('header XX-Device-Type字段值不符合!');
        //}
        //$this->deviceType = $deviceType;

        $urlArr = [
            'https://api.weixin.qq.com/sns/jscode2session',
            "?",
            "appid=$appid&",
            "secret=$appSecret&",
            "js_code=$code&",
            "grant_type=$grant_type"
        ];
        $url = implode("", $urlArr);

        //$response = cmf_curl_get($url);               //向微信API发送get请求
        $response = file_get_contents($url);            //向微信API发送get请求

        //$ret = get_object_vars($res);  //转换成数组
        $ret = json_decode($response, true);
        if (!empty($response['errcode'])) {
            $this->error('操作失败!');
        }
        //var_dump($ret);   //unionid，同一个开放平台添加的web页和小程序，获得的unionid是一样的
        /* res:
            array(3) {
                ["session_key"]=>
                    string(24) "6PdtKq1iXxIMJsSlSH2ggg=="
                ["openid"]=>
                    string(28) "oCS-o5HTEfhKVjL9EwtOAC_Zk760"
                ["unionid"]=>
                    string(28) "opKXO61L5ZYgdvwEoOiw35bCIYCs"
            }
         */
        
        //注意，如果接口报错，则会有errcode。如果接口正确，则不会有errcode和errmsg
        if (array_key_exists('errcode', $ret)) {
            $errcode = $ret['errcode'];
            $errmsg = $ret['errmsg'];
            if ($errcode != 0) {
                $this->error($errcode . ': 微信api接口auth.code2Session报错,' . $errmsg);
            }
        }

        $unionid = '';      //当前小程序已绑定到微信开放平台账号下才会返回。

        $openid     = $ret['openid'];
        $session_key = $ret['session_key'];
        if (isset($ret['unionid'])) {
            $unionid = $ret['unionid'];        //当前小程序已绑定到微信开放平台账号下才会返回。
        }else{
            $unionid = null;
        }

        $findThirdPartyUser = Db::name("third_party_user")
            ->where(['openid' => $openid,'app_id' => $appid])
            ->whereOr(['union_id' => $unionid])
            ->find();

        $currentTime = time();
        $ip          = $this->request->ip(0, true);

        if ($findThirdPartyUser) {

            $userId = $findThirdPartyUser['user_id'];
            $this->checkAppid($userId,$openid,$appid,$unionid,$ip,$currentTime);

            $token  = cmf_generate_user_token($userId, 'wxapp');

            $user = Db::name('user')->where('id', $userId)->find();

            if (!empty($user)) {
                $this->user     = $user;
                $this->userId   = $user['id'];
                $this->userType = $user['user_type'];
                $this->success("登录成功!", ['token' => $token, 'user' => $user]);
            } else {
                //没有此用户，则需要在微信小程序弹出注册页面
                $this->error('没有找到匹配用户！');
            }

        } else {

            //TODO 使用事务做用户注册
            $userID = Db::name("user")->insertGetId([
                'create_time'     => $currentTime,
                'user_status'     => 1,
                'user_type'       => 2,
                //'sex'             => $wxUserData['gender'],
                //'user_nickname'   => $wxUserData['nickName'],
                //'avatar'          => $wxUserData['avatarUrl'],
                'last_login_ip'   => $ip,
                'last_login_time' => $currentTime,
            ]);

            Db::name("third_party_user")->insert([
                'openid'          => $openid,
                'user_id'         => $userID,
                'third_party'     => 'wxapp',
                'app_id'          => $appid,
                'last_login_ip'   => $ip,
                'union_id'        => $unionid,
                'last_login_time' => $currentTime,
                'create_time'     => $currentTime,
                'login_times'     => 1,
                'status'          => 1,
                //'more'            => json_encode($wxUserData)
            ]);

            //返回：401用户没有绑定，小程序跳转到注册页；403用户状态错误
            if ($userID) {
                $token = cmf_generate_user_token($userID, 'wxapp');
                return json([
                    'code'=>401,'data'=>['token' => $token, 'userID' => $userID],
                    'msg'=>'请绑定员工!'
                ]);
            } else {
                $this->error('建立新用户失败！');
            }
        }
    }

    /**
     * 检查cmf_third_party_user表中用户数据
     * unionid 有没有对应的app_id，如果没有则增加，为每个用户的app_id添加出数据
     */
    public function checkAppid($userid,$openid,$appid,$unionid,$ip,$currentTime){
        //$s1 = Db::name("third_party_user")->where('unionid',$unionid)->find();
        $s2 = Db::name("third_party_user")
            ->where(['openid' => $openid,'app_id' => $appid])
            ->whereOr(['union_id' => $unionid,'app_id' => $appid])
            ->find();
        if ($s2){
            //更新用户登录时间和IP等
            $userData = [
                'union_id' => $unionid,
                'last_login_ip'   => $ip,
                'last_login_time' => $currentTime,
                'login_times'     => Db::raw('login_times+1'),
                //'more'            => json_encode($wxUserData)
            ];
            Db::name("third_party_user")
                ->where(['openid' => $openid,'app_id' => $appid])
                ->whereOr(['union_id' => $unionid,'app_id' => $appid])
                ->update($userData);

        }else{
            // 为用户的app_id新增cmf_third_party_user数据
            Db::name("third_party_user")->insert([
                'openid'          => $openid,
                'user_id'         => $userid,
                'third_party'     => 'wxapp',//见RestBaseController->allowedDeviceTypes，有['mobile', 'android', 'iphone', 'ipad', 'web', 'pc', 'mac', 'wxapp', 'ios', 'wechat']
                'app_id'          => $appid,
                'last_login_ip'   => $ip,
                'union_id'        => $unionid,
                'last_login_time' => $currentTime,
                'create_time'     => $currentTime,
                'login_times'     => 1,
                'status'          => 1,
                //'more'            => json_encode($wxUserData)
            ]);
        }
    }

}
